﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.UI
{
    //属性管理类
    public class PropertyManageCls : CollectionBase, ICustomTypeDescriptor
    {
        public bool Add(PropObject value)
        {
            if (value == null)
                return false;

            if (base.List.Count == 0)
            {
                base.List.Add(value);
                return true;
            }
            int count = 0;
            foreach (PropObject item in base.List)
            {
                if (item.Category == value.Category && item.Name == value.Name)
                    count++;
            }
            if (count == 0)
            {
                base.List.Add(value);
                return true;
            }
            return false;
        }
        public void Remove(PropObject value)
        {
            if (value != null && base.List.Count > 0)
                base.List.Remove(value);
        }
        public PropObject this[int index]
        {
            get
            {
                return (PropObject)base.List[index];
            }
            set
            {
                base.List[index] = (PropObject)value;
            }
        }
        #region ICustomTypeDescriptor 成员
        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }
        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }
        public string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }
        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this, true);
        }
        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }
        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }
        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }
        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(this, attributes, true);
        }
        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(this, true);
        }
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];
            for (int i = 0; i < this.Count; i++)
            {
                PropObject prop = (PropObject)this[i];
                newProps[i] = new CustomPropertyDescriptor(ref prop, attributes);
            }
            return new PropertyDescriptorCollection(newProps);
        }
        public PropertyDescriptorCollection GetProperties()
        {
            return TypeDescriptor.GetProperties(this, true);
        }
        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }
        #endregion
    }

    //属性类
    public class PropObject
    {
        private string _name = string.Empty;
        private object _value = null;
        private bool _readonly = false;
        private bool _visible = true;
        private string _category = string.Empty;
        private object _tag = null;
        TypeConverter _converter = null;
        object _editor = null;
        private string _displayname = string.Empty;

        public PropObject(string sName, object sValue)
        {
            this._name = sName;
            this._value = sValue;
        }

        public PropObject(string sName, object sValue, bool sReadonly, bool sVisible)
        {
            this._name = sName;
            this._value = sValue;
            this._readonly = sReadonly;
            this._visible = sVisible;
        }

        //获得属性名
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        //属性显示名称
        public string DisplayName
        {
            get { return _displayname; }
            set { _displayname = value; }
        }

        //类型转换器，我们在制作下拉列表时需要用到
        public TypeConverter Converter
        {
            get { return _converter; }
            set { _converter = value; }
        }

        //属性所属类别
        public string Category
        {
            get { return _category; }
            set { _category = value; }
        }

        //属性值
        public object Value
        {
            get { return _value; }
            set { _value = value; }
        }

        //Tag
        public object Tag
        {
            get { return _tag; }
            set { _tag = value; }
        }

        //是否为只读属性
        public bool ReadOnly
        {
            get { return _readonly; }
            set { _readonly = value; }
        }

        //是否可见(该功能暂时无效)
        public bool Visible
        {
            get { return _visible; }
            set { _visible = value; }
        }

        //属性编辑器
        public virtual object Editor
        {
            get { return _editor; }
            set { _editor = value; }
        }
    }

    public class CustomPropertyDescriptor : PropertyDescriptor
    {
        public PropObject PropObj;

        public CustomPropertyDescriptor(ref PropObject myProperty, Attribute[] attrs) : base(myProperty.Name, attrs)
        {
            PropObj = myProperty;
        }

        #region PropertyDescriptor 重写方法

        public override Type ComponentType
        {
            get { return null; }
        }
        public override string Description
        {
            get { return PropObj.Value.ToString(); }
        }
        public override string Category
        {
            get { return PropObj.Category; }
        }
        public override string DisplayName
        {
            get { return PropObj.DisplayName != "" ? PropObj.DisplayName : PropObj.Name; }
        }
        public override bool IsReadOnly
        {
            get { return PropObj.ReadOnly; }
        }
        public override bool IsBrowsable
        {
            get { return PropObj.Visible; }
        }
        public override TypeConverter Converter
        {
            get { return PropObj.Converter; }
        }
        public override Type PropertyType
        {
            get { return PropObj.Value?.GetType(); }
        }

        public override bool CanResetValue(object component)
        {
            return false;
        }
        public override object GetValue(object component)
        {
            return PropObj.Value;
        }
        public override void ResetValue(object component)
        {
            //暂时未实现
        }
        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }
        public override void SetValue(object component, object value)
        {
            PropObj.Value = value;
        }
        public override object GetEditor(Type editorBaseType)
        {
            return PropObj.Editor == null ? base.GetEditor(editorBaseType) : PropObj.Editor;
        }
        #endregion
    }

    public class DropDownListConverter : StringConverter
    {
        object[] m_Objects;

        public DropDownListConverter(object[] objects)
        {
            m_Objects = objects;
        }
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return true;//true下拉框不可编辑
        }
        public override
        System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(m_Objects);//我们可以直接在内部定义一个数组，但并不建议这样做，这样对于下拉框的灵活性有很大影响
        }
    }
}
